package com.ease.util {
	public class DateUtils {
		public static const MILLI_IN_WEEK:Number = 7*24*60*60*1000;
		public static const MILLI_IN_DAY:Number = 24*60*60*1000;
		public static const MILLI_IN_HOUR:Number = 60*60*1000;
		public static const MILLI_IN_MINUTE:Number = 60*1000;
		public static const MILLI_IN_SECOND:Number = 1000;
		
		public static const YEAR:String			= "fullYear";
		public static const MONTH:String		= "month";
		public static const WEEK:String			= "week";
		public static const DAY_OF_MONTH:String	= "date";
		public static const HOURS:String		= "hours";
		public static const MINUTES:String		= "minutes";
		public static const SECONDS:String		= "seconds";
		public static const MILLISECONDS:String	= "milliseconds";
		public static const DAY_OF_WEEK:String	= "day";

		public static function toIcsDate(d:Date, format:Boolean = false):String{
			var year:String;
			var month:String;
			var date:String;
			
			var dateStr:String;
			
			year = String(d.getFullYear());
			
			if(d.getMonth() + 1 < 10){
				month = "0" + (d.getMonth() + 1);
			}else{
				month = String(d.getMonth() + 1);
			}
			
			if(d.getDate() < 10){
				date = "0" + (d.getDate());
			}else{
				date = String(d.getDate());
			}
			if(format){
				dateStr =  month + "/" + date + "/" + year;
			}else{
				dateStr =  year + month + date;
			}
			return dateStr;
		}
		
		public static function toIcsMonth(d:Date, format:Boolean = false):String{
			var year:String;
			var month:String;
			var date:String;
			
			var dateStr:String;
			
			year = String(d.getFullYear());
			
			if(d.getMonth() + 1 < 10){
				month = "0" + (d.getMonth() + 1);
			}else{
				month = String(d.getMonth() + 1);
			}
			
			if(format){
				dateStr =  month + "/" + year;
			}else{
				dateStr =  year + month;
			}
			return dateStr;
		}
		
		public static function toIcsTime(d:Date, format:Boolean = false):String{
			
			var hour:String;
			var minute:String;
			var second:String;
			
			var timeStr:String;
			
			if(d.getHours() < 10){
				hour = "0" + (d.getHours());
			}else{
				hour = String(d.getHours());
			}
			
			if(d.getMinutes() < 10){
				minute = "0" + (d.getMinutes());
			}else{
				minute = String(d.getMinutes());
			}
			
			if(d.getSeconds() < 10){
				second = "0" + (d.getSeconds());
			}else{
				second = String(d.getSeconds());
			}
			if(format){
				timeStr =  hour + ":" +  minute + ":" + second;
			}else{
				timeStr =  hour + minute + second;
			}
			return timeStr;
		}
		
		/**
		 * Determines the number of "dateParts" difference between 2 dates
		 * 
		 * @param datePart	The part of the date that will be checked
		 * @param startDate	The starting date
		 * @param endDate	The ending date
		 * 
		 * @return			The number of "dateParts" difference
		 */
		public static function dateDiff( datePart:String, startDate:Date, endDate:Date ):Number {
			var _returnValue:Number = 0;

			switch ( datePart ) {
				case DateUtils.MILLISECONDS:
					_returnValue = endDate.time - startDate.time;
					break;
				case DateUtils.SECONDS:
					_returnValue = Math.floor( DateUtils.dateDiff( DateUtils.MILLISECONDS, startDate, endDate ) / DateUtils.MILLI_IN_SECOND );
					break;
				case DateUtils.MINUTES:
					_returnValue = Math.floor( DateUtils.dateDiff( DateUtils.MILLISECONDS, startDate, endDate ) / DateUtils.MILLI_IN_MINUTE );
					break;
				case DateUtils.HOURS:
					_returnValue = Math.floor( DateUtils.dateDiff( DateUtils.MILLISECONDS, startDate, endDate ) / DateUtils.MILLI_IN_HOUR );
					break;
				case DateUtils.DAY_OF_MONTH:
					// TODO: Need to figure out DST problem i.e. 23 hours at DST start, 25 at end.
					// Math.floor causes rounding down error with DST start at dayOfYear
					_returnValue = Math.floor( DateUtils.dateDiff( DateUtils.MILLISECONDS, startDate, endDate ) / DateUtils.MILLI_IN_DAY );
					break;
				case DateUtils.WEEK:
					_returnValue = Math.floor( DateUtils.dateDiff( DateUtils.MILLISECONDS, startDate, endDate ) / DateUtils.MILLI_IN_WEEK );
					break;
				case DateUtils.MONTH:
					// if start date is after end date, switch values and take inverse of return value
					if ( DateUtils.dateDiff( DateUtils.MILLISECONDS, startDate, endDate ) < 0 ) {
						_returnValue -= DateUtils.dateDiff( DateUtils.MONTH, endDate, startDate );
					} else {
						 // get number of months based upon years
						_returnValue = DateUtils.dateDiff( DateUtils.YEAR, startDate, endDate ) * 12;
						// subtract months then perform test to verify whether to subtract one month or not
						// the check below gets the correct starting number of months (but may need to have one month removed after check)
						if ( endDate.month != startDate.month ) {
							_returnValue += ( endDate.month <= startDate.month ) ? 12 - startDate.month + endDate.month : endDate.month - startDate.month;
						}
						// have to perform same checks as YEAR
						// i.e. if end date day is <= start date day, and end date milliseconds < start date milliseconds
						if ( ( endDate[ DateUtils.DAY_OF_MONTH ] < startDate[ DateUtils.DAY_OF_MONTH ] ) ||
								( endDate[ DateUtils.DAY_OF_MONTH ] == startDate[ DateUtils.DAY_OF_MONTH ] &&
									endDate[ DateUtils.MILLISECONDS ] < startDate[ DateUtils.MILLISECONDS ] ) ) {
							_returnValue -= 1;
						}
					}
					break;
				case DateUtils.YEAR:
					_returnValue = endDate.fullYear - startDate.fullYear;
					// this fixes the previous problem with dates that ran into 2 calendar years
					// previously, if 2 dates were in separate calendar years, but the months were not > 1 year apart, then it was returning too many years
					// e.g. 11/2008 to 2/2009 was returning 1, but should have been returning 0 (zero)
					// if start date before end date and months are less than 1 year apart, add 1 to year to fix offset issue
					// if end date before start date and months are less than 1 year apart, subtract 1 year to fix offset issue
					// added month and milliseconds check to make sure that a date that was e.g. 9/11/07 9:15AM would not return 1 year if the end date was 9/11/08 9:14AM
					if ( _returnValue != 0 ) {
						// if start date is after end date
						if ( _returnValue < 0 ) {
							// if end date month is >= start date month, and end date day is >= start date day, and end date milliseconds > start date milliseconds
							if ( ( endDate[ DateUtils.MONTH ] > startDate[ DateUtils.MONTH ] ) ||
									( endDate[ DateUtils.MONTH ] == startDate[ DateUtils.MONTH ] && endDate[ DateUtils.DAY_OF_MONTH ] > startDate[ DateUtils.DAY_OF_MONTH ] ) ||
									( endDate[ DateUtils.MONTH ] == startDate[ DateUtils.MONTH ] && endDate[ DateUtils.DAY_OF_MONTH ] == startDate[ DateUtils.DAY_OF_MONTH ] &&
										endDate[ DateUtils.MILLISECONDS ] > startDate[ DateUtils.MILLISECONDS ] ) ) {
								_returnValue += 1;
							}
						} else {
							// if end date month is <= start date month, and end date day is <= start date day, and end date milliseconds < start date milliseconds
							if ( ( endDate[ DateUtils.MONTH ] < startDate[ DateUtils.MONTH ] ) ||
									( endDate[ DateUtils.MONTH ] == startDate[ DateUtils.MONTH ] && endDate[ DateUtils.DAY_OF_MONTH ] < startDate[ DateUtils.DAY_OF_MONTH ] ) ||
									( endDate[ DateUtils.MONTH ] == startDate[ DateUtils.MONTH ] && endDate[ DateUtils.DAY_OF_MONTH ] == startDate[ DateUtils.DAY_OF_MONTH ] &&
										endDate[ DateUtils.MILLISECONDS ] < startDate[ DateUtils.MILLISECONDS ] ) ) {
								_returnValue -= 1;
							}
						}
					}
					break;
			
			}

			return _returnValue;
			
		}
		
		public static function fromIscTime(data:String,format:Boolean = false):Date{
			var dateArr:Array = data.split(":");
			var ret:Date = new Date();
			if(dateArr.length == 3){
				ret.hours = Number(dateArr[0]);
				ret.minutes = Number(dateArr[1]);
				ret.seconds = Number(dateArr[2]);
			}
			return ret;
		}
		
		public static function fromIscDate(data:String,format:Boolean = false):Date{
			
			var year:Number = Number(data.substr(0,4));
			var month:Number = Number(data.substr(4,2));
			var date:Number = Number(data.substr(6,8));
			
			var ret:Date = new Date(year,month,date);
			
			return ret;
		}
		
	}
}

